Spring Boot 如何集成JWT实现Token验证

您所在的位置:网站首页 spring jwt认证 Spring Boot 如何集成JWT实现Token验证

Spring Boot 如何集成JWT实现Token验证

2023-03-29 13:54| 来源: 网络整理| 查看: 265

近年来,随着前后端分离、微服务等架构的兴起,传统的cookie+session身份验证模式已经逐渐被基于Token的身份验证模式取代。接下来介绍如何在Spring Boot项目中集成JWT实现Token验证。

一、JWT入门1.什么是JWT

JWT (Json web token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519)。它定义了一种紧凑的,自包含的方式,用于通信双方之间以JSON对象的形式安全传递信息。JWT使用HMAC算法或者是RSA的公私秘钥的数字签名技术,所以这些信息是可被验证和信任的。

JWT官网:https://jwt.io/

JWT(Java版)的github地址:https://github.com/jwtk/jjwt

2.JWT的结构

在使用 JWT 前,需要先了解它的组成结构。它是由以下三段信息构成的:

Header 头部(包含签名和/或加密算法的类型)Payload 载荷 (存放有效信息)Signature 签名/签证

将这三段信息文本用‘.’连接一起就构成完整的JWT字符串,也是就我们需要的Token。如下所示:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0aW1lU3RhbXAiOjE2MzkwNDc1NTMxNjksInVzZXJSb2xlIjoiUk9MRV9BRE1JTiIsInVzZXJJZCI6ImFkbWluIn0.UFQLvaiQ1AThx9Fa4SRqNg-b9HPJ9y1TlgQB4-F3pi0

JWT的数据结构还是比较复杂的,Header,Payload,Signature中包含了很多信息,建议大家最好是能够了解。

3.JWT的请求流程

JWT的请求流程也特别简单,首先使用账号登录获取Token,然后后面的各种请求,都带上这个Token即可。具体流程如下:

1. 客户端发起登录请求,传入账号密码;

2. 服务端使用私钥创建一个Token;

3. 服务器返回Token给客户端;

4. 客户端向服务端发送请求,在请求头中该Token;

5. 服务器验证该Token;

6. 返回结果。

二、Spring Boot 如何集成JWT

JWT提供了基于Java组件:java-jwt帮助我们在Spring Boot项目中快速集成JWT,接下来进行SpringBoot和JWT的集成。

1.引入JWT依赖

创建普通的Spring Boot项目,修改项目中的pom.xml文件,引入JWT等依赖。示例代码如下:

com.auth0 java-jwt 3.10.3 org.springframework.boot spring-boot-starter-web 2.创建&验证Token

创建通用的处理类TokenUtil,负责创建和验证Token。示例代码如下:

@Component public class TokenUtil { @Value("${token.secretKey}") private String secretKey; /** * 加密token. */ public String getToken(String userId, String userRole) { //这个是放到负载payLoad 里面,魔法值可以使用常量类进行封装. String token = JWT .create() .withClaim("userId" ,userId) .withClaim("userRole", userRole) .withClaim("timeStamp", System.currentTimeMillis()) .sign(Algorithm.HMAC256(secretKey)); return token; } /** * 解析token. * { * "userId": "weizhong", * "userRole": "ROLE_ADMIN", * "timeStamp": "134143214" * } */ public Map parseToken(String token) { HashMap map = new HashMap(); DecodedJWT decodedjwt = JWT.require(Algorithm.HMAC256(secretKey)) .build().verify(token); Claim userId = decodedjwt.getClaim("userId"); Claim userRole = decodedjwt.getClaim("userRole"); Claim timeStamp = decodedjwt.getClaim("timeStamp"); map.put("userId", userId.asString()); map.put("userRole", userRole.asString()); map.put("timeStamp", timeStamp.asLong().toString()); return map; } }3.创建拦截器,验证Token

创建一个拦截器AuthHandlerInterceptor,负责拦截所有Http请求,验证Token是否有效。示例代码如下:

@Slf4j @Component public class AuthHandlerInterceptor implements HandlerInterceptor { @Autowired TokenUtil tokenUtil; @Value("${token.refreshTime}") private Long refreshTime; @Value("${token.expiresTime}") private Long expiresTime; /** * 权限认证的拦截操作. */ @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception { log.info("=======进入拦截器========"); // 如果不是映射到方法直接通过,可以访问资源. if (!(object instanceof HandlerMethod)) { return true; } //为空就返回错误 String token = httpServletRequest.getHeader("token"); if (null == token || "".equals(token.trim())) { return false; } log.info("==============token:" + token); Map map = tokenUtil.parseToken(token); String userId = map.get("userId"); String userRole = map.get("userRole"); long timeOfUse = System.currentTimeMillis() - Long.parseLong(map.get("timeStamp")); //1.判断 token 是否过期 if (timeOfUse < refreshTime) { log.info("token验证成功"); return true; } //超过token刷新时间,刷新 token else if (timeOfUse >= refreshTime && timeOfUse < expiresTime) { httpServletResponse.setHeader("token",tokenUtil.getToken(userId,userRole)); log.info("token刷新成功"); return true; } //token过期就返回 token 无效. else { throw new TokenAuthExpiredException(); } } }

拦截器创建之后,需要将拦截器注册到Spring Boot中。这和其他的拦截器注册是一样的。示例代码如下:

@Configuration public class AuthWebMvcConfigurer implements WebMvcConfigurer { @Autowired AuthHandlerInterceptor authHandlerInterceptor; /** * 给除了 /login 的接口都配置拦截器,拦截转向到 authHandlerInterceptor */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authHandlerInterceptor) .addPathPatterns("/**") .excludePathPatterns("/login"); } }4.创建控制器

创建TokenTestController控制器,处理HTTP请求。示例代码如下:

@RestController public class TokenTestController { @Autowired TokenUtil tokenUtil; @PostMapping("/login") public String login(@RequestBody LoginUser user){ // 先验证用户的账号密码,账号密码验证通过之后,生成Token String role = "ROLE_ADMIN"; String token = tokenUtil.getToken(user.username,role); return token; } @PostMapping("/testToken") public String testToken(HttpServletRequest request){ String token = request.getHeader("token"); tokenUtil.parseToken(token); return "请求成功"; } }5.测试验证

集成JWT成功之后,接下来验证Token是否成功,启动项目。在Postman中调用相关接口,验证功能是否正常。

首先,调用http://localhost:8080/testToken,获取token

然后,调用http://localhost:8080/testToken 验证token是否有效。

最后

以上,我们就把Spring Boot集成JWT实现Token验证介绍完了。身份验证是Web开发中非常基础的功能,后面还会介绍授权及权限管理等内容。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3